﻿Module ModNetworks

    Public Sub InitNetworks()

        Try

            ' Create the new socket then starts listening.

            Listener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            Listener.Bind(New IPEndPoint(IPAddress.Any, Settings.ServerPORT))
            Listener.Listen(100)

            ' Loop acceptance.

            While (True)
                AllDones.Reset()
                AddText("En attente d'une connexion entrante sur " & CType(Listener.LocalEndPoint, IPEndPoint).Port & " ...")
                Listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallBack), Listener)
                AllDones.WaitOne()
            End While

        Catch ex As Exception
            AddText(ex.Message)
        End Try

    End Sub

    Private Sub AcceptCallBack(ByVal IResult As IAsyncResult)

        Try

            Dim Listener As Socket = CType(IResult.AsyncState, Socket)
            Dim Index As Integer

            ' Test client not connecting then assigns the communication.

            For Index = 1 To Settings.MaximumPlayers
                If Not Clients(Index).IsConnected Then
                    Clients(Index).WorkSocket = Listener.EndAccept(IResult)
                    Clients(Index).AddressIP = CType(Clients(Index).WorkSocket.RemoteEndPoint, IPEndPoint).Address.ToString
                    Clients(Index).Index = Index
                    Clients(Index).WorkSocket.BeginReceive(Clients(Index).Buffer, SocketFlags.None, New AsyncCallback(AddressOf ReceiveCallBack), Index)
                    Exit For
                End If
            Next

            ' Return to the main

            AllDones.Set()

            ' Restart the Acceptance

            Listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallBack), Listener)

        Catch ex As Exception
            AddText(ex.Message)
        End Try

    End Sub

    Private Sub ReceiveCallBack(ByVal IResult As IAsyncResult)

        Try

            Dim Index As Integer = CType(IResult.AsyncState, Integer)
            Dim ReadS As Integer = Clients(Index).WorkSocket.EndReceive(IResult)

            ' Check if the data has a lenght greather than zero.

            If (ReadS > 0) Then

                ' Decode Data.

                Clients(index).BufferText &= Encoding.UTF8.GetString(Clients(index).Buffer)

                Dim Start As Integer = Clients(index).BufferText.IndexOf(EndDatas)
                Dim Packet As String = String.Empty

                ' Just remove the packet.

                Do While Start > 0
                    Packet = Clients(index).BufferText.Substring(0, Start)
                    Clients(index).BufferText = Clients(index).BufferText.Substring(Start, Clients(index).BufferText.Length)
                    Start = Clients(index).BufferText.IndexOf(EndDatas)
                    If Packet.Length > 0 Then HandleData(Index, Packet)
                Loop

                ' ReStart the reception.

                Clients(Index).WorkSocket.BeginReceive(Clients(index).Buffer, SocketFlags.None, New AsyncCallback(AddressOf ReceiveCallBack), Index)

            End If

        Catch ex As Exception
            AddText(ex.Message)
        End Try

    End Sub


#Region "Handle Data"

    Private Sub HandleData(ByVal index As Integer, ByVal Data As String)
        Dim ErrorText As String = String.Empty

        Try

            ' Separate data.

            Dim Parse() As String = Data.Split(SepDatas)

            ' Process Data.
            ' --> Select the header.

            Select Case CInt(Parse(0))

                ' -
                ' - NEW ACCOUNT PACKET.
                ' - 

                Case Packets.NewAccount

                    Dim Login As String = Parse(1).Trim
                    Dim Password As String = Parse(2).Trim
                    Dim Mail As String = Parse(3).Trim

                    ' Login has a lenght invalid.

                    If Login.Length < 3 And Login.Length > 25 Then

                    End If

                    Dim RegexLogin As New RegularExpressions.Regex("/[a-zA-Z]|\d/")

                    ' Login has a char invalid.

                    If Not RegexLogin.IsMatch(Login) Then

                    End If

                    ' Passord has a lenght invalid.

                    If Password.Length < 5 And Password.Length > 25 Then

                    End If

                    Dim RegexMail As New RegularExpressions.Regex("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#")

                    ' The Mail is invalid.

                    If Not RegexMail.IsMatch(Mail) Then

                    End If

                    ' If the message is empty we continue else we send the error to the client

                    If ErrorText = String.Empty Then
                        Account.CreateNewAccount(index, Login, Password, Mail)
                    Else
                        ErrorMessage(index, ErrorText)
                        Exit Sub
                    End If

                    Exit Sub

            End Select

        Catch ex As Exception
            AddText(ex.Message)
        End Try

    End Sub

#End Region

#Region "Packets"

    Public Sub ErrorMessage(ByVal Index As Integer, ByVal Message As String)
        Clients(Index).SendData(Packets.ErrorMessage & SepDatas & Message.Trim & SepDatas & EndDatas)
    End Sub

    Public Sub InfosMessage(ByVal Index As Integer, ByVal Message As String)
        Clients(Index).SendData(Packets.InfosMessage & SepDatas & Message.Trim & SepDatas & EndDatas)
    End Sub

    Public Sub SendCharacters(ByVal Index As Integer)

        Dim Packet As String = Packets.SendCharacters & SepDatas

        ' Loop {for} for have all characters.

        For i As Integer = 1 To Settings.MaximumCharacters
            With Accounts(Index).Character(i)
                Packet &= Accounts(Index).Character(i).Name & SepDatas & Classes(.Classe).Name & SepDatas & .Level & SepDatas
            End With
        Next

        Packet &= EndDatas

        Clients(Index).SendData(Packet)

    End Sub

#End Region

End Module
